package sym.qrcode.j2se;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

import javax.imageio.ImageIO;

import sym.qrcode.CoverCrucialPointException;
import sym.qrcode.decoder.Version;
import sym.qrcode.encoder.ByteMatrix;

public class DisguiseImage {
	
	private static final int BLACK = 0xFF000000;
	private static final int WHITE = 0xFFFFFFFF;
	
	public static Rectangle reBuildVersionRect(Version ver, int imageSize)
			throws CoverCrucialPointException {
		int[] alignmentCenters = ver.getAlignmentPatternCenters();
		int alignmentLen = alignmentCenters.length;
		int maxImageLen = 0;

		if (alignmentLen == 0) {
			maxImageLen = 3;
		} else {
			if (alignmentLen % 2 == 1) {
				maxImageLen = alignmentCenters[(int) (alignmentLen / 2) + 1]
						- alignmentCenters[(int) (alignmentLen / 2) - 1] - 5;
			} else if (alignmentLen % 2 == 0) {
				maxImageLen = alignmentCenters[(int) (alignmentLen / 2)]
						- alignmentCenters[(int) (alignmentLen / 2) - 1] - 5;
			}
			// if(alignmentCenters[(int) (alignmentLen / 2) - 1]==6){
			// maxImageLen += 2;
			// }
		}
		if (imageSize > maxImageLen || imageSize < 5) {
			System.out.println("imagesize: " + imageSize + "maxImageLen: "
					+ maxImageLen);
			throw new CoverCrucialPointException();
		}
		int center = 0;

		if (alignmentLen % 2 == 1) {
			center = alignmentCenters[(int) (alignmentLen / 2)];
		} else if (alignmentLen % 2 == 0) {
			center = alignmentCenters[(int) (alignmentLen / 2) - 1] + 3
					+ maxImageLen / 2;
		}
		// if(alignmentCenters[(int) (alignmentLen / 2) - 1]==6){
		// center--;
		// }
		return new Rectangle(center - imageSize / 2, center - imageSize / 2,
				imageSize, imageSize);
	}

	public static ArrayList<Point> getAvaliablePoints(BufferedImage image, Rectangle rect, int scale,ByteMatrix matrix,Version ver){
		int width = image.getWidth();
		int height = image.getHeight();

		ArrayList<Point> list = new ArrayList<Point>();

		for (int i = 0; i < height; i += scale) {
			for (int j = 0; j < width; j += scale) {
				boolean isWhiteBlock = true;
				out: for (int k = 0; k < scale; k++) {
					for (int l = 0; l < scale; l++) {
						if (image.getRGB(j + k, i + l) != Color.white.getRGB()) {
							isWhiteBlock = false;
							break out;
						}
					}
				}
				if (!isWhiteBlock)
					break;
				else
					list.add(new Point(j, i));
			}

			for (int j = width - scale; j >= 0; j -= scale) {
				boolean isWhiteBlock = true;
				out: for (int k = 0; k < scale; k++) {
					for (int l = 0; l < scale; l++) {
						if (image.getRGB(j + k, i + l) != Color.white.getRGB()) {
							isWhiteBlock = false;
							break out;
						}
					}
				}
				if (!isWhiteBlock)
					break;
				else {
					boolean isInList = false;
					for (Point p : list) {
						if (j == p.x && i == p.y) {
							isInList = true;
							break;
						}
					}
					if (!isInList)
						list.add(new Point(j, i));
				}
			}
		}
		ArrayList<Point> resultList = new ArrayList<Point>();
		for (Point p : list) {
			resultList.add(new Point(p.x/scale,p.y/scale));
		}
		return resultList;
	}
	public static BufferedImage Disguise(BufferedImage image, Rectangle rect, int scale,ByteMatrix matrix,Version ver, Color findPatternColor, Color foregroundColor, Color backgroundColor) {
		int width = image.getWidth();
		int height = image.getHeight();

		ArrayList<Point> list = new ArrayList<Point>();

		for (int i = 0; i < height; i += scale) {
			for (int j = 0; j < width; j += scale) {
				boolean isWhiteBlock = true;
				out: for (int k = 0; k < scale; k++) {
					for (int l = 0; l < scale; l++) {
						if (image.getRGB(j + k, i + l) != Color.white.getRGB()) {
							isWhiteBlock = false;
							break out;
						}
					}
				}
				if (!isWhiteBlock)
					break;
				else
					list.add(new Point(j, i));
			}

			for (int j = width - scale; j >= 0; j -= scale) {
				boolean isWhiteBlock = true;
				out: for (int k = 0; k < scale; k++) {
					for (int l = 0; l < scale; l++) {
						if (image.getRGB(j + k, i + l) != Color.white.getRGB()) {
							isWhiteBlock = false;
							break out;
						}
					}
				}
				if (!isWhiteBlock)
					break;
				else {
					boolean isInList = false;
					for (Point p : list) {
						if (j == p.x && i == p.y) {
							isInList = true;
							break;
						}
					}
					if (!isInList)
						list.add(new Point(j, i));
				}
			}
		}

		int imagewidth = matrix.getWidth();
		int imageheight = matrix.getHeight();
		

		BufferedImage result = new BufferedImage(imagewidth * scale, imageheight * scale,
				BufferedImage.TYPE_INT_RGB);
		BufferedImage  image2 = null;
		try {
			image2 = ImageIO.read(new File("C:\\box2.jpg"));		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		BufferedImage tag2 = new BufferedImage((int) scale,  
                (int)scale, BufferedImage.TYPE_INT_RGB);  
		tag2.getGraphics().drawImage(  
	        		image2.getScaledInstance((int) scale,
	        				scale,  
	                        Image.SCALE_SMOOTH), 0, 0, null);

		for (int x = 0; x < imagewidth; x++) {
			for (int y = 0; y < imageheight; y++) {
				for (int i = 0; i < scale; i++) {
					for (int j = 0; j < scale; j++) {
//						if(!rect.contains(x, y))
//							result.setRGB(x * scale + i, y * scale + j,
//								matrix.get(x, y) != 0 ? (matrix.get(x,y)!=1?findPatternColor.getRGB():foregroundColor.getRGB()) : backgroundColor.getRGB());
//						else{
//							boolean isWhite = false;
//							
//							for (Point p : list) {
//								if(p.x/scale+rect.x == x&&p.y/scale+rect.y == y){
//									result.setRGB(x * scale + i, y * scale + j,
//											matrix.get(x, y) != 0 ? (matrix.get(x,y)!=1?findPatternColor.getRGB():foregroundColor.getRGB()) : backgroundColor.getRGB());
//									isWhite = true;
//									break;
//								}
//							}
//							if(!isWhite)
//								result.setRGB(x * scale + i, y * scale + j, image.getRGB((x - rect.x)*scale+i, (y-rect.y)*scale+j));							
//						}				
//					}
//				}
				if(!rect.contains(x, y)){
					if(matrix.get(x,y)!=0)
						result.setRGB(x * scale + i, y * scale + j,tag2.getRGB(i,j));
					else
						result.setRGB(x * scale + i, y * scale + j,Color.white.getRGB());
				}
				else{
					boolean isWhite = false;
					
					for (Point p : list) {
						if(p.x/scale+rect.x == x&&p.y/scale+rect.y == y){
							if(matrix.get(x,y)!=0)
								result.setRGB(x * scale + i, y * scale + j,tag2.getRGB(i,j));
							else
								result.setRGB(x * scale + i, y * scale + j,Color.white.getRGB());
							isWhite = true;
							break;
						}
					}
					if(!isWhite){
						result.setRGB(x * scale + i, y * scale + j, image.getRGB((x - rect.x)*scale+i, (y-rect.y)*scale+j));							
					}
				}
					}
				}
			}
		}

		return result;
	}

	private static void setBlack(Point p, int scale, BufferedImage result) {
		// TODO Auto-generated method stub
		for (int i = 0; i < scale; i++) {
			for (int j = 0; j < scale; j++) {
				result.setRGB(p.x + i, p.y + j, Color.black.getRGB());
			}
		}
	}
}
